package com.rockcent.service.impl;

import com.rockcent.common.common.BusinessException;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.ExcelCreateUtils;
import com.rockcent.helper.IntegrationCashCouponHelper;
import com.rockcent.mall.lib.domain.IntegrationChannel;
import com.rockcent.mall.lib.domain.IntegrationCouponWallet;
import com.rockcent.mall.lib.domain.MerchantCoupon;
import com.rockcent.mall.lib.dto.IntegrationChannelDto;
import com.rockcent.mall.lib.dto.IntegrationCouponDetailRespDto;
import com.rockcent.mall.lib.dto.IntegrationCouponRespDto;
import com.rockcent.mall.lib.dto.IntegrationCouponWalletDto;
import com.rockcent.mall.lib.repository.IntegrationCouponWalletRepository;
import com.rockcent.service.IntegrationCashCouponWalletSrv;
import com.rockcent.service.IntegrationChannelSrv;
import com.rockcent.service.IntegrationCouponWalletSrv;
import com.rockcent.service.MerchantCouponSrv;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by zhangjh on 2016/12/17.
 */
@Service
public class IntegrationCouponWalletSrvImpl implements IntegrationCouponWalletSrv {

    @Autowired
    private MerchantCouponSrv merchantCouponSrv;
    static Map<String, String> titleMap = new HashMap<>();

    static {
        titleMap.put("flagCode", "卡券标识码");
        titleMap.put("name", "卡券名称");
        titleMap.put("faceValue", "面值");
        titleMap.put("merchantName", "所属商户");
        titleMap.put("exchangeDate", "兑换时间");
        titleMap.put("receiveDate", "领取时间");
        titleMap.put("batchPutNo", "编号");
    }

    @Autowired
    private IntegrationCouponWalletRepository integrationCouponWalletRepository;

    @Autowired
    private IntegrationChannelSrv integrationChannelSrv;

    /**
     * @param exchangeCode
     * @param exchangeNum
     * @param receiveNum
     * @param useNum
     * @return
     */
    @Override
    public IntegrationCouponWallet findByExchangeCodeAndExchangeNumAndReceiveNumAndUseNum(String exchangeCode, long exchangeNum, long receiveNum, long useNum) {
        return integrationCouponWalletRepository.findByExchangeCodeAndExchangeNumAndReceiveNumAndUseNum(exchangeCode, exchangeNum, receiveNum, useNum);
    }

    /**
     * @param integrationCouponWallet
     * @return
     */
    @Override
    public IntegrationCouponWallet save(IntegrationCouponWallet integrationCouponWallet) {
        return integrationCouponWalletRepository.save(integrationCouponWallet);
    }

    /**
     * @param cashCouponId
     * @param integrationChannelId
     * @param mallId
     * @return
     */
    @Override
    public IntegrationCouponWallet caculateCoupon(Long cashCouponId, Long integrationChannelId, Long mallId) {
        return integrationCouponWalletRepository.caculateCoupon(cashCouponId, integrationChannelId, mallId);
    }

    @Override
    public PageResult<IntegrationCouponWalletDto> findChannelCouponDetail(IntegrationChannelDto dto, Long mallId, Whether whether, PageResult page) {
        return integrationCouponWalletRepository.findChannelCouponDetail(dto, mallId, whether, page);
    }

    /**
     * @param dto
     * @param mallId
     * @param whether
     * @return
     */
    @Override
    public Long qrExchangeNumByChannelId(IntegrationChannelDto dto, Long mallId, Whether whether) {
        return integrationCouponWalletRepository.qrExchangeNumByChannelId(dto, mallId, whether);
    }


    /**
     * @param request
     * @param response
     * @param dto
     * @param mallId
     * @param no
     * @throws IOException
     * @throws InvalidFormatException
     */
    @Override
    public void exportExchangeCoupon(HttpServletRequest request, HttpServletResponse response, IntegrationChannelDto dto, Long mallId, Whether no) throws IOException, InvalidFormatException {
        PageResult page = new PageResult(0, Integer.MAX_VALUE);
        PageResult<IntegrationCouponWalletDto> pageResult = findChannelCouponDetail(dto, mallId, Whether.NO, page);


        Long total = 0l;// qrExchangeNumByChannelId(dto, mallId, Whether.NO);
        List<IntegrationCouponWalletDto> items = pageResult.data;
        if (null == items || items.isEmpty()) {
            items = new ArrayList<>();
        }
        total = Long.valueOf(items.size());
        Long channelId = dto.getId();
        IntegrationChannel integrationChannel = integrationChannelSrv.findOne(dto.getId());
        Double exchangeNumCouponAmount = qrExchangeNumCouponAmountByChannelId(dto, mallId, Whether.NO);

//        BigDecimal availableAmount = merchantCouponSrv.queryAvailableAmountByMallId(mallId,channelId);
        if (null == integrationChannel) {
            throw new BusinessException("渠道信息不正确");
        }
        List<String> titles = dto.getTitles();
        List names = new ArrayList();

        for (String title : titles) {
            String name = titleMap.get(title);
            names.add(name);
        }

        Map<String, Object> data = new HashMap<>();
        String fileName = integrationChannel.getName();
        data.put("total", total == null ? 0 : total);
        data.put("name", fileName);
        data.put("typeName", "优惠券");
        data.put("data", items);
        data.put("headers", names);
        data.put("availableAmount", String.valueOf(exchangeNumCouponAmount));
        String objectProps = StringUtils.join(titles, ",");
        String dataName = "data";
        ExcelCreateUtils.getInstance().createDynamic(data, dataName, fileName + IntegrationCashCouponWalletSrv.SUFFIX_XLSX, response, IntegrationCashCouponWalletSrv.RESOURCE_PATH_INTEGRATION_CHANNEL_CASH_DETAIL_DYNAMIC, objectProps);

//        ExcelCreateUtils.getInstance().create(data, dataName, fileName + IntegrationCashCouponWalletSrv.SUFFIX_XLSX, response, IntegrationCashCouponWalletSrv.RESOURCE_PATH_INTEGRATION_CHANNEL_CASH_DETAIL_DYNAMIC);
    }

    /**
     * @param merchantCouponId
     * @param mallId
     */
    @Override
    public void stop(Long merchantCouponId, Long mallId) {
        integrationCouponWalletRepository.stop(merchantCouponId, mallId);
    }

    /**
     * @param merchantCouponId
     * @param channelId
     * @param mallId
     * @param batchPutNo
     * @param merchantName
     */
    @Override
    public void updateIntegrationChannelId(Long merchantCouponId, Long channelId, Long mallId, Long batchPutNo, String merchantName) {
        integrationCouponWalletRepository.updateIntegrationChannelId(merchantCouponId, channelId, mallId, batchPutNo, merchantName);
    }

    /**
     * @param coupon
     */
    @Override
    public void batchSave(MerchantCoupon coupon) {
        Long count = coupon.getQuantity();
//        List<String> codeList = IntegrationCashCouponHelper.SINGLETNONE.getExchangeCode("coupon", count);
        Map<String, String> codeMap = IntegrationCashCouponHelper.SINGLETNONE.getExchangeCodeAndFlagCode("coupon", count);

        BigDecimal faceValue = coupon.getFaceValue();
        Long mallId = coupon.getMallId();
        Long couponId = coupon.getId();
        Long merchantId = coupon.getMerchantId();
        for (Map.Entry<String, String> entry : codeMap.entrySet()) {
            IntegrationCouponWallet wallet = new IntegrationCouponWallet();
            wallet.setFaceValue(faceValue);
            wallet.setMallId(mallId);
            wallet.setExchangeCode(entry.getKey());
            wallet.setFlagCode(entry.getValue());
            wallet.setReceiveNum(0l);
            wallet.setExchangeNum(0l);
            wallet.setUseNum(0l);
            wallet.setMerchantId(merchantId);
            wallet.setCouponId(couponId);
            integrationCouponWalletRepository.save(wallet);
        }

    }

    /**
     * @param channelId
     * @return
     */
    @Override
    public List<IntegrationCouponRespDto> queryList(Long channelId) {
        return integrationCouponWalletRepository.queryList(channelId);
    }

    /**
     * @param exchangeCode
     * @return
     */
    @Override
    public IntegrationCouponWallet findByExchangeCode(String exchangeCode) {
        return integrationCouponWalletRepository.findByExchangeCode(exchangeCode);
    }

    /**
     * @param exchangeCode
     * @param channelId
     * @param no
     * @param exchangeNum
     * @return
     */
    @Override
    public IntegrationCouponWallet findByExchangeCodeAndIntegrationChannelIdAndIsDeleteAndExchangeNum(String exchangeCode, Long channelId, Whether no, long exchangeNum) {
        return integrationCouponWalletRepository.findTop1ByExchangeCodeAndIntegrationChannelIdAndIsDeleteAndExchangeNum(exchangeCode, channelId, Whether.NO, 0l);
    }

    /**
     * @param dto
     * @param mallId
     * @param no
     * @return
     */
    @Override
    public Double qrExchangeNumCouponAmountByChannelId(IntegrationChannelDto dto, Long mallId, Whether no) {
        return integrationCouponWalletRepository.qrExchangeNumCouponAmountByChannelId(dto, mallId, no);
    }

    /**
     * @param couponId
     * @return
     */
    @Override
    public List<IntegrationCouponDetailRespDto> findByCounponId(Long couponId) {
        return integrationCouponWalletRepository.findByCounponId(couponId);
    }


    /**
     * @param exchangeCode
     * @param integrationChannelId
     * @param no
     * @return
     */
    @Override
    public IntegrationCouponWallet findByExchangeCodeAndIntegrationChannelIdAndIsDelete(String exchangeCode, Long integrationChannelId, Whether no) {
        return integrationCouponWalletRepository.findByExchangeCodeAndIntegrationChannelIdAndIsDelete(exchangeCode, integrationChannelId, no);
    }

    /**
     *
     * @param id
     * @param integrationChannelId
     * @param no
     * @param exchangeNum
     * @return
     */
    @Override
    public IntegrationCouponWallet findTop1ByIdAndIntegrationChannelIdAndIsDeleteAndExchangeNum(Long id, Long integrationChannelId, Whether no, long exchangeNum) {
        return integrationCouponWalletRepository.findTop1ByCouponIdAndIntegrationChannelIdAndIsDeleteAndExchangeNum(id, integrationChannelId, no, exchangeNum);
    }

}
